home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Ken Long / Lightspeed-p-c / Metrowerks / C / LightSpeed.c next >
Encoding:
Text File  |  1994-12-04  |  11.6 KB  |  563 lines  |  [TEXT/MMCC]

  1.  
  2. //• C translation from Pascal source file: LightSpeed.p
  3. //• by Kenneth A. Long, at itty bitty bytes(tm), on 19 November 1994.
  4. //• Original Pascal by Jonathan Birge.
  5.  
  6. //• LightSpeed.c
  7.  
  8. #include <Sound.h>
  9. #include <math.h>
  10.  
  11. enum {
  12. //    MBarHeight = 0xBAA, //• Address of menubar height.
  13.     HUDColor = blackColor,
  14.     IndexColor = greenColor,
  15.     starNumber = 40,  //• Number of stars on the screen at one time.
  16.     photonSnd = 9000,
  17.     engineSnd = 9001
  18. };
  19.  
  20. typedef short *IntPtr;
  21. typedef struct {
  22.     double h, v;
  23.     double distance;
  24. } StarRecord;
  25.  
  26. enum {
  27.     PhotonNum = 18,
  28.     maxDist = 24
  29. };
  30.  
  31. typedef struct {
  32.     float h;
  33.     float v;
  34.     double pSize;
  35. } PhotonVector;
  36.  
  37. RGBColor starColor;
  38. short star, i, t;
  39. short hPos, vPos;
  40. PhotonVector photon[PhotonNum];
  41. PhotonVector oldPhoton;
  42. short photonCount;
  43. double oldpsize;
  44. Boolean keepRunning, past, offscreen;
  45. double shipSpeed, dist;
  46. Rect starRect;
  47. short windowWidth, windowHight, midH, midV;
  48. Point mouseLoc, oldmouseLoc;
  49. short hOffset, vOffset;
  50. Rect hRect, vRect;
  51. Handle engineSound, photonSound;
  52. SndChannelPtr soundChannel;
  53. SndCommand stopCommand;
  54. OSErr err;
  55.  
  56. typedef StarRecord StarList[starNumber];
  57.  
  58. StarList stars;
  59. WindowPtr starsWindow;
  60. Handle dataHandle;
  61. GrafPtr currentPort;
  62. Rect starswindowRect;
  63. RgnHandle GrayRgn;
  64. short *mBarHeightPtr;
  65. short oldMBarHeight;
  66. RgnHandle mBarRgn;
  67. short colorList[3];
  68. EventRecord theEvent;
  69.  
  70. #include <SANE.h>
  71.  
  72. //• Random number between -(high) and (high).
  73. double Randomize (short high)
  74. {
  75.     long rawResult;
  76.  
  77.     rawResult = Random  ();
  78.     return (((rawResult * high) / 32768));
  79. }
  80.  
  81. //• Pos number between low and high.
  82. double RandMinMax (double low, double high)
  83. {
  84.     long rawResult;
  85.     
  86.     rawResult = Random  ();
  87.     return (rawResult * (high - low) / 32768) + low;
  88. }
  89.  
  90. //• Random integer between 1 and high.
  91. short IntRandomize (short range)
  92. {
  93.     long rawResult;
  94.  
  95.     rawResult = Random  ();
  96.     return ((rawResult * range) / 32768);
  97. }
  98.  
  99. short Sgn (short number)
  100. {
  101.     if (number > 0)
  102.         return (1);
  103.     else 
  104.         if (number < 0)
  105.             return (-1);
  106.     else
  107.         return (0);
  108. }
  109.  
  110. short noSgn (short number)
  111. {
  112.     return (0);
  113.     if (number > 0)
  114.         return (1);
  115.     if (number < 0)
  116.         return (-1);
  117. }
  118.  
  119. void HideMenuBar ()
  120. {
  121.     Rect mBarRect;
  122.  
  123.     oldMBarHeight = *mBarHeightPtr;
  124.  
  125.     //• Make the Menu Bar's height zero.
  126.     *mBarHeightPtr = 0;
  127.     mBarRect = qd.screenBits.bounds; 
  128.     mBarRect.bottom = mBarRect.top + oldMBarHeight;                        
  129.     mBarRgn = NewRgn ();
  130.     RectRgn (mBarRgn, &mBarRect);
  131.     UnionRgn (GrayRgn, mBarRgn, GrayRgn); //• Tell the desktop it.
  132.     
  133.     //• covers the menu bar.
  134.     PaintOne (0L, mBarRgn);  //• Redraw desktop.
  135. }
  136.  
  137. void ShowMenuBar ()
  138. {
  139.     *mBarHeightPtr = oldMBarHeight;
  140.  
  141.     //• Remove the menu bar from the desktop.
  142.     DiffRgn (GrayRgn, mBarRgn, GrayRgn);  
  143.     DisposeRgn (mBarRgn);
  144. }
  145.  
  146. void CenterOrigin ()
  147. {
  148.     short centerX, centerY;
  149.  
  150.     centerX = - (qd.screenBits.bounds.right / 2);
  151. //    centerX = - (abs (currentPort->portRect.right / 2));
  152.     centerY = - (qd.screenBits.bounds.bottom / 2);
  153. //    centerY = - (abs (currentPort->portRect.bottom / 2));
  154.     SetOrigin (centerX, centerY);
  155. }
  156.  
  157. void ClearScrn ()
  158. {
  159.     short oldPenState, oldBkColor;
  160.     GrafPtr winMgrPort;
  161.     Rect menuRect;
  162.  
  163.     oldPenState = currentPort->pnMode;
  164.     GetWMgrPort (&winMgrPort);
  165.     oldBkColor = winMgrPort->bkColor;
  166.     SetPort (winMgrPort);
  167.     BackColor (blackColor);
  168.     SetRect (&menuRect, 0, 0, qd.screenBits.bounds.right, 20);
  169.     EraseRect (&winMgrPort->portRect);
  170.     BackColor (oldBkColor);
  171.     SetPort (currentPort);
  172. }
  173.  
  174. void MakeRect (double h, double v, double distance, Rect *theRect)
  175. {
  176.     short Size;
  177.  
  178.     Size = ceil (maxDist / (distance + 0.01));
  179.     theRect->left = ceil (h);
  180.     theRect->top = ceil (v);
  181.     theRect->right = theRect->left + Size;
  182.     theRect->bottom = theRect->top + Size;
  183.     OffsetRect (theRect, - (Size / 2), - (Size / 2));
  184.  
  185. }
  186.  
  187. void LoadStars ()
  188. {
  189.     short star;
  190.     Rect starRect;
  191.     
  192.     for (star = 1; star <= starNumber; star++)
  193.     {
  194.         stars[star].h = Randomize (midH);
  195.         stars[star].v = Randomize (midV);
  196.         stars[star].distance = RandMinMax (3, maxDist);
  197.  
  198.         MakeRect (stars[star].h, 
  199.                   stars[star].v, 
  200.                   stars[star].distance, &starRect);
  201.  
  202.         InvertOval (&starRect);
  203.     }
  204. }
  205.     
  206. void DoMouseDown ()
  207. {
  208.     if (photonCount < 10)
  209.     {
  210.         err = SndDoImmediate (soundChannel, &stopCommand);
  211.         err = SndPlay (soundChannel, photonSound, true);
  212.         photon[photonCount + 1].h = -midH;
  213.         photon[photonCount + 1].v = midV;
  214.         photon[photonCount + 2].h = midH;
  215.         photon[photonCount + 2].v = midV;
  216.         photon[photonCount + 1].pSize = 48;
  217.         photon[photonCount + 2].pSize = 48;
  218.         photonCount = photonCount + 2;
  219.     }
  220. }
  221.     
  222. void DoKeyDown (EventRecord *theEvent)
  223. {
  224.     short    chCode;
  225.     chCode = theEvent->message & charCodeMask;
  226.     
  227.     switch (chCode) 
  228.     {
  229.         case '+':
  230.             shipSpeed = shipSpeed + 0.1;
  231.         break;
  232.         
  233.         case '-':
  234.             shipSpeed = shipSpeed - 0.1;
  235.         break;
  236.         
  237.         case 'q':
  238.         case 'Q':
  239.             keepRunning = false;
  240.         break;
  241.         
  242.         case '0':
  243.             shipSpeed = 0;
  244.         break;
  245.         
  246.         case ' ':
  247.             DoMouseDown ();
  248.         break;
  249.         
  250.         case '4':
  251.             hPos = hPos - 5;
  252.         break;
  253.         
  254.         case '6':
  255.             hPos = hPos + 5;
  256.         break;
  257.         
  258.         case '8':
  259.             vPos = vPos + 5;
  260.         break;
  261.  
  262.         case '5':
  263.             vPos = vPos - 5;
  264.         break;
  265.         
  266.         case '1':
  267.         {
  268.             vPos = 0;
  269.             hPos = 0;
  270.         }
  271.         break;
  272.     }
  273. }
  274.  
  275. void DrawPhoton (float h, float v, double pSize)
  276. {
  277.     short t, offset, offset2;
  278.     short h2, v2;
  279.     Rect photonRect;
  280.  
  281.     colorList[1] = blueColor;
  282.     colorList[0] = magentaColor;
  283.     colorList[2] = cyanColor;
  284.  
  285.     h2 = ceil (h);
  286.     v2 = ceil (v);
  287.     for (t = 0; t < 4; t++)
  288.     {
  289.         ForeColor (colorList[IntRandomize (3)]);
  290.         offset = ceil (sin (pSize + t) * pSize);
  291.         offset2 = ceil (sin ((pSize + t) * 2) * pSize);
  292.         
  293.         MoveTo (h2 - offset, v2 - offset2);
  294.         LineTo (h2 + offset, v2 + offset2);
  295.     }
  296. }
  297.  
  298. void MainLoop ()
  299. {
  300.     CenterOrigin ();
  301.     BackColor (blackColor);
  302.     
  303.     windowWidth = qd.screenBits.bounds.right;
  304. //    windowWidth = (currentPort->portRect.right - currentPort->portRect.left);
  305.     windowHight = qd.screenBits.bounds.bottom;
  306. //    windowHight = (currentPort->portRect.bottom - currentPort->portRect.top);
  307.  
  308.     midH = windowWidth / 2;
  309.     midV = windowHight / 2;
  310.     LoadStars ();
  311.     ForeColor (HUDColor);
  312.     PenNormal ();
  313.     PenPat (&qd.black);
  314.     engineSound = GetResource ('snd ', engineSnd);
  315.     photonSound = GetResource ('snd ', photonSnd);
  316.     
  317.     stopCommand.cmd = quietCmd;
  318.     stopCommand.param1 = 0;
  319.     stopCommand.param2 = 0;
  320.  
  321.     soundChannel = 0L;
  322.     err = SndNewChannel (&soundChannel, sampledSynth, initMono, 0L);
  323.  
  324.     keepRunning = true;
  325.     photonCount = 0;
  326.     shipSpeed = 0;
  327.     hPos = 0;
  328.     vPos = 0;
  329.     
  330.     starColor.red     = 0xffff;
  331.     starColor.green = 0xffff;
  332.     starColor.blue     = 0xbbbb;
  333.  
  334.     SetEventMask (mDownMask + keyDownMask + autoKeyMask);
  335.     GetMouse (&oldmouseLoc);
  336.     while (keepRunning)
  337.     {
  338.         if (GetNextEvent (everyEvent, &theEvent))
  339.             switch (theEvent.what)
  340.             {
  341.                 case mouseDown: 
  342.                     DoMouseDown ();
  343.                 break;
  344.                 
  345.                 case keyDown: 
  346.                 case autoKey: 
  347.                     DoKeyDown (&theEvent);
  348.                 break;
  349.                 
  350.                 default:
  351.                 break;
  352.             }
  353.             //• Moves the direction indicators.
  354.             GetMouse (&mouseLoc);
  355.             if (! EqualPt (mouseLoc, oldmouseLoc))
  356.             {
  357.                 hPos = hPos + (mouseLoc.h - oldmouseLoc.h);
  358.                 vPos = vPos + (mouseLoc.v - oldmouseLoc.v);
  359.                 oldmouseLoc = mouseLoc;
  360.             }
  361.             //• Draws the index bars.
  362.             ForeColor (IndexColor);        //• Green color.
  363.             PenMode (srcCopy);
  364.             
  365.             if (abs (hPos) > (midH - 2))
  366.                 hPos = Sgn (hPos) * (midH - 2);
  367.                 
  368.             if (abs (vPos) > (midV - 2))
  369.                 vPos = Sgn (vPos) * (midV - 2);
  370.                 
  371.             vRect.left = - (midH);
  372.             vRect.right = - (midH) + 8;
  373.             vRect.top = vPos;
  374.             vRect.bottom = vPos + 2;
  375.             PaintRect (&vRect);
  376.             
  377.             hRect.bottom = midV;
  378.             hRect.top = midV - 8;
  379.             hRect.left = hPos;
  380.             hRect.right = hPos + 2;
  381.             PaintRect (&hRect);
  382.             
  383.             hOffset = -hPos;
  384.             vOffset = vPos;
  385.             PenMode (srcCopy);
  386.             
  387.             //• If there are any photons...
  388.             if (photonCount > 0)
  389.             {
  390.                 PenMode (srcCopy);
  391.                 for (i = 1; i <= photonCount; i++)
  392.                     DrawPhoton (photon[i].h,         //• Horizontal.
  393.                                 photon[i].v,         //• Vertical.
  394.                                 photon[i].pSize);    //• Size.
  395.             }
  396.             
  397.             //• Calculate new star position.
  398.             //• If star out of window, reset it.
  399.             for (star = 1; star <= starNumber; star++)  
  400.             {
  401.                 MakeRect (stars[star].h, stars[star].v, stars[star].distance, &starRect);
  402.                 EraseOval (&starRect);
  403.                 
  404.                 if ((shipSpeed < 0) && (stars[star].distance >= maxDist))
  405.                     past = true;
  406.                     
  407.                 if ((shipSpeed > 0) && (stars[star].distance <= 0))
  408.                     past = true;
  409.                     
  410.                 if ((/*abs*/ (stars[star].v) > midV) || (/*abs*/ (stars[star].h) > midH))
  411.                     offscreen = true;
  412.                     
  413.                 //• Create a new star.
  414.                 if ((past || offscreen))
  415.                 {
  416.                     past = false;
  417.                     offscreen = false;
  418.                     if (shipSpeed >= 0)
  419.                     {
  420.                         stars[star].v = Randomize (midV - 10);
  421.                         stars[star].h = Randomize (midH - 10);
  422.                         stars[star].distance = maxDist;
  423.                     }
  424.                     else //• shipSpeed < 0.
  425.                         switch (IntRandomize (3))
  426.                         {
  427.                             case 1: 
  428.                             {
  429.                                 if (IntRandomize (2) == 1)
  430.                                     stars[star].v = midV;
  431.                                 else
  432.                                     stars[star].v = -midV;
  433.                                     
  434.                                 stars[star].h = Randomize (midH);
  435.                                 stars[star].distance = RandMinMax (2, maxDist - 1);
  436.                             }
  437.                             break;
  438.                             
  439.                             case 2: 
  440.                             {
  441.                                 stars[star].v = Randomize (midV);
  442.                                 if (IntRandomize (2) == 1)
  443.                                     stars[star].h = midH;
  444.                                 else
  445.                                     stars[star].h = -midH;
  446.                                     
  447.                                 stars[star].distance = RandMinMax (2, maxDist - 1);
  448.                             }
  449.                             break;
  450.                         }
  451.                 }  //• new star.
  452.                 else
  453.                     {
  454.                         dist = 6 * stars[star].distance;
  455.                          
  456.                         //• How much distance affects apparent speed.
  457.                         stars[star].h = stars[star].h * (shipSpeed + dist) / dist + 
  458.                                                         (hOffset / 8);
  459.                                                         
  460.                         stars[star].v = stars[star].v * (shipSpeed + dist) / dist + 
  461.                                                         (vOffset / 6);
  462.                                                         
  463.                         stars[star].distance = stars[star].distance - (shipSpeed / 6);
  464.                 }
  465.                 
  466.                 MakeRect (stars[star].h, stars[star].v, stars[star].distance, &starRect);
  467.  
  468.                 RGBForeColor (&starColor);
  469.                 PaintOval (&starRect);
  470.             }
  471.             
  472.             //• Draw the "heads up" display (sight).
  473.             //• Moved to here so stars and photons don't erase it.
  474.             PenPat (&qd.gray);
  475.             ForeColor (yellowColor);
  476.             i = 0;
  477.             while (i < midH)
  478.             {
  479.                 i = i + 50;
  480.                 MoveTo (i, -5);
  481.                 Line (0, 10);
  482.                 MoveTo (-i, -5);
  483.                 Line (0, 10);
  484.             }
  485.             i = 0;
  486.             while (i < midV)
  487.             {
  488.                 i = i + 50;
  489.                 MoveTo (-5, i);
  490.                 Line (10, 0);
  491.                 MoveTo (-5, -i);
  492.                 Line (10, 0);
  493.             }    //• Done drawing sight.
  494.             
  495.             PenNormal ();
  496.             
  497.             //• If there are photons, we want them to disappear 
  498.             //• in the distance.
  499.             if (photonCount > 0)
  500.             {
  501.                 PenMode (srcBic);
  502.                 for (i = 1; i <= photonCount; i++)
  503.                 {
  504.                     oldPhoton = photon[i];
  505.                     photon[i].h = photon[i].h * 0.86 + (hOffset / 8);
  506.                     photon[i].v = photon[i].v * 0.86 + (vOffset / 6);
  507.     
  508.                     DrawPhoton (oldPhoton.h, oldPhoton.v, oldPhoton.pSize);
  509.     
  510.                     oldpsize = photon[i].pSize;
  511.                     
  512.                     photon[i].pSize = photon[i].pSize * 0.9;
  513.                     
  514.                     //• Reduced to double and abs removed to make
  515.                     //• it work at half the value.
  516.                     //• This part kills the farthest photon.
  517.                     if ((oldpsize - photon[i].pSize) < 0.09)
  518.                     {
  519.                         for (t = i; t <= (photonCount - 1); t++)
  520.                             photon[t] = photon[t + 1];
  521.                         photonCount = photonCount - 1;
  522.                     }
  523.                 }
  524.             }
  525.             EraseRect (&hRect);
  526.             EraseRect (&vRect);
  527.     }
  528.     ReleaseResource (photonSound);
  529.     ReleaseResource (engineSound);
  530.     err = SndDisposeChannel (soundChannel, true);
  531.     SetEventMask (everyEvent);
  532. }
  533.  
  534. main ()
  535. {
  536.     InitGraf(&qd.thePort);
  537.     InitFonts();
  538.     FlushEvents(everyEvent, 0);
  539.     InitWindows();
  540.     InitMenus();
  541.     TEInit();
  542.     InitDialogs(0);
  543.     
  544.     InitCursor();
  545.  
  546.     MaxApplZone ();
  547.     
  548.     GetDateTime ((unsigned long *) qd.randSeed);
  549.     
  550.     mBarHeightPtr = (short *)  0x0BAA;
  551.     GrayRgn = GetGrayRgn ();
  552.     HideMenuBar ();
  553.     starsWindow = NewCWindow (0L, &qd.screenBits.bounds, "\pLightSpeed", true, noGrowDocProc, (WindowPtr)-1L, false, (long) dataHandle);
  554.     SetPort (starsWindow);
  555.  
  556.     GetPort (¤tPort);
  557.     ClearScrn ();
  558.     HideCursor ();
  559.     MainLoop ();
  560.     ShowCursor ();
  561.     ShowMenuBar ();
  562.     FlushEvents (mDownMask, 0);    //• Clear Event Queue of all mouseDown events.
  563. }